﻿using System.Collections.ObjectModel;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Markup;
using Ops.Mpc.Collections;
using Ops.Mpc.Controllers;


namespace Ops.Mpc.States
{
    [ContentProperty("StateTemplate")]
    public class State : DependencyObject, IState
    {
        #region Fields & Properties
        private NamedItemCollection<StateAction> _stateActions;
        private IController _controller = null;
       
        public static readonly DependencyProperty ItemNameProperty = DependencyProperty.Register("ItemName", typeof(string), typeof(State), null);
        public string ItemName
        {
            get
            {
                return (string)this.GetValue(ItemNameProperty);
            }

            set
            {
                this.SetValue(ItemNameProperty, value);
            }
        }

        public static readonly DependencyProperty AutoRunProperty = DependencyProperty.Register("AutoRun", typeof(bool), typeof(State), new PropertyMetadata(false));
        public bool AutoRun
        {
            get
            {
                return (bool)this.GetValue(AutoRunProperty);
            }

            set
            {
                this.SetValue(AutoRunProperty, value);
            }
        }

        public NamedItemCollection<StateAction> StateActions
        {
            get
            {
                return this._stateActions;
            }
        }

        public IStateTemplate StateTemplate
        {
            get;
            set;
        }

        public IController Controller
        {
            get
            {
                return this._controller;
            }

            set
            {
                this._controller = value;
                foreach (IStateAction iStateAction in this._stateActions)
                    iStateAction.Controller = this._controller;
            }
        }

        public string DisplayName
        {
            get;
            set;
        }

        #endregion

        #region Constructors
        public State()
        {
            this._stateActions = new NamedItemCollection<StateAction>();
            this._stateActions.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(OnStateActionsChanged);
         }


        #endregion 

        #region Methods
        public void Start()
        {
            foreach (IStateAction iStateAction in this._stateActions)
                iStateAction.Start();
        }

        public void Stop()
        {
            foreach (IStateAction iStateAction in this._stateActions)
                iStateAction.Stop();
        }

        private void OnStateActionsChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            if (e.Action == NotifyCollectionChangedAction.Add)
            {
                foreach (IStateAction iStateAction in e.NewItems)
                {
                    iStateAction.Controller = this.Controller;
                }
            }
        }


        public IStateAction GetStateAction(string name, bool traverseUpLogicalTree)
        {
            foreach (IStateAction iStateAction in this._stateActions)
                if (iStateAction.ItemName == name)
                    return iStateAction;

            if (traverseUpLogicalTree)
                return this._controller.GetParentStateAction(name);
            else
                return null;
        }

        public IStateAction GetFirstStateAction()
        {
            if (this._stateActions != null && this._stateActions.Count > 0)
                return this._stateActions[0];
            else
                return null;
        }

        public void OnEnteringState()
        {
            foreach (IStateAction iStateAction in this._stateActions)
                iStateAction.OnEnteringState();
        }

        public void OnLeavingState()
        {
            foreach (IStateAction iStateAction in this._stateActions)
                iStateAction.OnLeavingState();
        }

        public override string ToString()
        {
            return this.ItemName;
        }
        #endregion

    }
}
